import { Injectable, EventEmitter } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BaseHttpService } from '../../../../shared/services/baseHttp.service';
import { Observable } from 'rxjs/Observable';
import { RiskCompanyModel } from './models/riskCompany.model';
import { UniverseBenchmarkModel, SubIndustryBenchmarkModel, IndustryBenchmarkModel, MeiBenchmarkModel } from './models/riskBenchmark.model';
import { RiskMeiModel } from './mei/models/riskMei.model';
import { RiskExposureModel } from './models/riskExposure.model';
import { EventIndicatorModel } from './mei/models/riskEvent.model';
import { LocationModel } from '../../../../shared/models/location.model';
import { IndicatorModel } from '../shared/companyIndicator/models/indicator.model';
import { AnalyticsService } from '../../../../shared/services/googleAnalytics.service';
import { GoogleAnalyticsBeacon } from '../../../../shared/models/googleAnalytics.model';
import { ReplaySubject } from 'rxjs';

/**
 * Company risk rating service
 *
 * Author: Sorin Spiru
 * Date: 13.01.2018
 */
@Injectable()
export class CompanyRiskRatingService extends BaseHttpService {    
    public company: Observable<RiskCompanyModel>;

    public mei: Observable<RiskMeiModel>;

    public meiIndustryExposure: Observable<RiskExposureModel[]>

    public meiIndustryBenchmark: Observable<MeiBenchmarkModel>;

    public meiExposure: Observable<any[]>

    constructor(private http: HttpClient) {
        super();
    }

    /**
     * Get company risk data by company id
     * @param companyId Company unique identifier
     */
    public getCompanyById(companyId: string): Observable<RiskCompanyModel> {        
        return this.http.get<RiskCompanyModel>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId).shareReplay(1);
    }

    /**
     * Get company's universe benchmark data
     * @param companyId Company unique identifier
     */
    public getCompanyUniverseBenchmark(companyId: string): Observable<UniverseBenchmarkModel> {
        return this.http.get<UniverseBenchmarkModel>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/benchmark/universe');
    }

    public getUniverseExposure(): Observable<any> {
        return this.http.get<any>(this.serverUrl + 'riskratingserv/api/v1/company/' + undefined + '/benchmark/exposure/universe')
    }

    public getBaselineExposure(): Observable<any[]> {
        return this.http.get<any[]>(this.serverUrl + 'riskratingserv/api/v1/company/' + undefined + '/benchmark/exposure/baseline')
    }

    public getMeiExposure(externalId: number): Observable<any[]> {
        return this.http.get<any[]>(this.serverUrl + 'riskratingserv/api/v1/company/' + undefined + '/benchmark/exposure/mei/' + externalId).shareReplay(1);
    }

    /**
     * Get the company's sub industry benchmark data
     * @param companyId Company unique identifier
     */
    public getCompanySubIndustryBenchmark(companyId: string): Observable<SubIndustryBenchmarkModel> {
        return this.http.get<SubIndustryBenchmarkModel>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/benchmark/subindustry');
    }

    /**
     * Get the company's industry benchmark data
     * @param companyId Company unique identifier
     */
    public getCompanyIndustryBenchmark(companyId: string): Observable<IndustryBenchmarkModel> {
        return this.http.get<SubIndustryBenchmarkModel>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/benchmark/industry');
    }

    /**
     * Get a MEI's sub industry benchmark data. MEI belongs to a company
     * @param companyId Company unique identifier
     * @param externalId Mei unique identifier
     */
    public getCompanyMeiBenchmark(companyId: string, externalId: number): Observable<MeiBenchmarkModel> {
        return this.http.get<MeiBenchmarkModel>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/benchmark/mei/' + externalId).shareReplay(1);
    }

    /**
     * Get risk exposures of companies within same sub industry as input company
     * @param companyId Company unique identifier
     */
    public getCompanySubIndustryExposure(companyId: string): Observable<RiskExposureModel[]> {
        return this.http.get<RiskExposureModel[]>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/benchmark/exposure');
    }

    /**
     * Get risk exposure of provided MEI within company's sub industry
     * @param companyId Company unique identifier
     * @param externalId Mei unique identifier
     */
    public getCompanyMeiSubIndustryExposure(companyId: string, externalId: number): Observable<RiskExposureModel[]> {
        return this.http.get<RiskExposureModel[]>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/benchmark/mei/' + externalId + '/exposure').shareReplay(1);
    }

    /**
     * Get MEI (Material ESG Issue)
     * @param companyId Company unique identifier
     * @param externalId Mei unique identifier
     */
    public getMeiById(companyId: string, externalId: number): Observable<RiskMeiModel> {       
        return this.http.get<RiskMeiModel>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/mei/' + externalId).shareReplay(1);
    }

    /**
     * Get risk indicator. Belongs to a MEI that belongs to a company
     * @param serverUrl Server Url. Because this method might be called by an external module that does not implement BaseHttpService, we provide this url
     * @param companyId Company unique identifier
     * @param externalId Mei unique identifier
     * @param code Indicator unique identifier
     */
    public getMEIIndicatorByCode(serverUrl: string, companyId: string, externalId: string, code: string, analyticsService: AnalyticsService, http: HttpClient): Observable<IndicatorModel> {
        analyticsService.sendBeacon(new GoogleAnalyticsBeacon('ESG RR Indicators', 'ESG Risk Rating', { CompanyId: companyId, ExternalId: externalId, Code: code }));        
        return http.get<IndicatorModel>(serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/mei/' + externalId + '/indicator/' + code);
    }

    /**
     * Get core risk indicator
     * @param serverUrl Server Url. Because this method might be called by an external module that does not implement BaseHttpService, we provide this url
     * @param companyId Company unique identifier
     * @param externalId Mei unique identifier
     * @param code Indicator unique identifier
     */
    public getIndicatorByCode(serverUrl: string, companyId: string, externalId: string, code: string, analyticsService: AnalyticsService, http: HttpClient): Observable<IndicatorModel> {
        analyticsService.sendBeacon(new GoogleAnalyticsBeacon('ESG RR Indicators', 'ESG Risk Rating', { CompanyId: companyId, ExternalId: externalId, Code: code }));
        return http.get<IndicatorModel>(serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/indicator/' + code);
    }

    /**
     * Get risk event
     * @param companyId Company unique identifier
     * @param code Event indicator unique identifier
     */
    public getEventsByCode(companyId: string, code: string): Observable<EventIndicatorModel> {
        return this.http.get<EventIndicatorModel>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/event/' + code);
    }

    /**
     * Get locations of event indicator
     * @param companyId Company unique identifier
     * @param code Event indicator unique identifier
     */
    public getLocationByEventCode(companyId: string, code: string): Observable<LocationModel[]> {
        return this.http.get<LocationModel[]>(this.serverUrl + 'riskratingserv/api/v1/company/' + companyId + '/event/' + code + '/locations');
    }

    /**
     * Get message text corresponding to the risk availability status
     * @param availability Availability status code
     */
    public researchStatusText(availability: number): string {
        switch(availability){
            default:
            case 2:
                return 'Research not available';
            case 3:
                return 'Research in progress';
            case 4:
                return 'Research available with additional subscriptions';
            case 5:
                return 'Framework not applicable';
        }
    }

    public getPillarDetails(companyId: string, number: string): Observable<any>
    {
        return this.http.get<any>(this.serverUrl + '/riskratingserv/api/v1/company/' + companyId + '/pillar/' + number);
    }

    public getCoreIndentPercentile(companyId: string){
        return this.http.get<any>(this.serverUrl + '/riskratingserv/api/v1/company/' + companyId + '/indentPercentile');
    }
}